
#include "test_mm.h"

enum _test_mm_dtype{
	TM0,
	TM1,
	TD0,
	TD1
};

static void test_mm_printDescriptor(enum _test_mm_dtype dtype){

	MemoryPageDescriptor* mIndex = NULL;
	DynamicObjectDescriptor* dIndex = NULL;
	uint32 nIndex = 1;

	switch (dtype){
	case TM0:
		DEBUGLOG("System Free Memory Page Descriptor:");
		mIndex = *(mmGetSystemFreeMPDListHeadPtr());
		goto _test_mm_printd_mpd;
		break;
	case TM1:
		DEBUGLOG("System Used Memory Page Descriptor:");
		mIndex = *(mmGetSystemUsedMPDListHeadPtr());
		goto _test_mm_printd_mpd;
		break;
	case TD0:
		DEBUGLOG("System Free Dynamic Object Descriptor:");
		dIndex = *(mmGetSystemFreeDODListHeadPtr());
		goto _test_mm_printd_dod;
		break;
	case TD1:
		DEBUGLOG("System Used Dynamic Object Descriptor:");
		dIndex = *(mmGetSystemUsedDODListHeadPtr());
		goto _test_mm_printd_dod;
		break;
	};
	
	_test_mm_printd_mpd:
		while(mIndex != NULL){
			DEBUGLOG("%d. Address: %8x, PMA Start: %8x, VMA Start: %8x, Size: %8x, Prev: %8x, Next: %8x",
					nIndex, mIndex, mIndex->pmaStart, mIndex->vmaStart, mIndex->size, mIndex->prev, mIndex->next);
			mIndex = mIndex->next;
			nIndex++;
		}
		DEBUGLOG("End Of Memory Page Descriptor");
		return;

	_test_mm_printd_dod:
		while(dIndex != NULL){
			DEBUGLOG("%d. Address: %8x, Start: %8x, Size: %8x, Prev: %8x, Next: %8x",
					nIndex, dIndex, dIndex->start, dIndex->size, dIndex->prev, dIndex->next);
			dIndex = dIndex->next;
			nIndex++;
		}
		DEBUGLOG("End Of Dynamic Object Descriptor");
		return;
}

static void test_mm_printAllDescriptors(void){
	test_mm_printDescriptor(TM0);
	test_mm_printDescriptor(TM1);
	test_mm_printDescriptor(TD0);
	test_mm_printDescriptor(TD1);
	return;
}

void test_mm(void){
	
	uint32 index = 0;
	byte* dobjHolder[10];
	SyscallDescriptor scd;
	SyscallReturnDescriptor scrd;
	
	DEBUGLOG("TEST SETS: MEMORY MANAGEMENT MODULE");
	
	DEBUGLOG("TC1 - DYNAMIC ALLOC 10 OBJECTS, WITH 5000 BYTES EACH");
	
	for (index = 0; index < 10; ++index){
		dobjHolder[index] = (byte*)mmSysMAlloc(5000);
		if (dobjHolder[index] == NULL){
			ERRORLOG("OBJECT POINTER IS NULL");
		}else{
			DEBUGLOG("%d. START ADDR: %8x", index + 1, dobjHolder[index]);
		}
	}
	test_mm_printAllDescriptors();
	
	DEBUGLOG("");
	
	DEBUGLOG("TC2 - REMOVE THOSE 10 OBJECTS");
	
	for (index = 0; index < 10; ++index){
		sint8 retVal = mmSysMFree((void*)(dobjHolder[index]));
		if (retVal != 0){
			ERRORLOG("ERROR ON DELETE DOBJ: %d", retVal);
		}else{
			DEBUGLOG("DELETE SUCCESS");
		}
	}
	test_mm_printAllDescriptors();
	
	DEBUGLOG("");
	
	DEBUGLOG("TC3 - TEST SYSMALLOC SYSCALL");
	
	scd.cmd = SYSCMDSYSMALLOC;
	scd.payload.sysmallocSize = 256;
	SYSCALLPTR(&scd, &scrd);
	
	if (scrd.ifSuccess == TRUE){
		DEBUGLOG("SYSMALLOC SYSCALL SUCCESS: Start: %8x", (uint32)(scrd.payload.sysmallocRetPtr));
	} else {
		ERRORLOG("SYSMALLOC SYSCALL FAILED");
	}
	
	DEBUGLOG("");
	
	DEBUGLOG("TC4 - TEST SYSFREE SYSCALL");
	
	scd.cmd = SYSCMDSYSFREE;
	scd.payload.sysfreePtr = scrd.payload.sysmallocRetPtr;
	SYSCALLPTR(&scd, &scrd);
	
	if (scrd.ifSuccess == TRUE){
		DEBUGLOG("SYSFREE SYSCALL SUCCESS");
	} else {
		ERRORLOG("SYSFREE SYSCALL FAILED");
	}
	
	test_mm_printAllDescriptors();
	
	return;
}
